/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>

*/
package cmd

import (
	"context"
	"os"

	"gitee.com/bjf-fhe/apicat/aggregation"
	"gitee.com/bjf-fhe/apicat/entry/etype"
	"gitee.com/bjf-fhe/apicat/entry/handler"
	"gitee.com/bjf-fhe/apicat/errors"
	"gitee.com/bjf-fhe/apicat/notify"
	"gitee.com/bjf-fhe/apicat/platform"
	"gitee.com/bjf-fhe/apicat/source"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

var notifyConfig handler.Config

// watchCmd represents the watch command
var watchCmd = &cobra.Command{
	Use:   "watch",
	Short: "实时监听日志，推送错误警报",
	Long:  `对日志的实时生成条目进行即时增量读取，对其中的错误情况按配置汇报给下游，实现安全联动`,
	Run: func(cmd *cobra.Command, args []string) {

		logrus.Infoln("开始执行Apicat监控程序")

		dest, _ := cmd.Flags().GetString("dest")

		ctx, cancel := context.WithCancel(context.Background())
		logrus.Warnf("使用%s作为监控输出", dest)

		api, baseUrl, err := rootConfig.LoadApi(true)

		if err == nil {

			if len(args) > 0 {

				rootConfig.File = args[0]

				if err != nil {
					cmd.PrintErr("打开日志文件出错", err)
					os.Exit(1)
				}

				// var notifier notify.Notifier
				var reader source.Reader
				var notifiChan handler.EntryHandler
				var err error
				var judgement = handler.NewJudgement(&notifyConfig)

				if rootConfig.RemoteAggregationAsMain {
					var server *aggregation.Server
					server, err = aggregation.NewServer(rootConfig.RemoteAggregationMainServer, judgement, ctx)
					notifiChan = server
					reader = server
				} else {
					reader, err = platform.GetSource(rootConfig.SourceMode, &rootConfig, ctx, true)
					if err == nil {
						notifier, err := platform.GetNotifier(dest, ctx, &rootConfig)
						if rootConfig.RemoteAggregationAsSub {
							notifiChan, err = aggregation.NewGrpcClient(rootConfig.RemoteAggregationMainServer, ctx, notifier)
							if err != nil {
								cancel()
							}
						} else {
							notifiChan, err = notify.GetHandler(dest, notifier, judgement)
						}
					}
				}

				if err != nil {
					logrus.Fatal(errors.Wrap(err, errors.NotifierRunError))
				}

				logrus.Warnf("使用%s作为监控输入", rootConfig.SourceMode)
				if err != nil {
					logrus.Errorln(errors.Wrap(err, errors.SourceReadError))
					os.Exit(1)
				}

				if err != nil {
					cmd.PrintErrln(err)
					os.Exit(1)
				}
				var handlers = handler.NewHandlers(ctx,
					notifiChan,
				)

				err = handlers.Handle(reader, &rootConfig, api, baseUrl)

				cancel()
				if err != nil {
					cmd.PrintErr("读取日志内容出错", err)
					os.Exit(1)
				}

			} else {
				cancel()
				cmd.PrintErr("没有指定日志文件路径")
				os.Exit(1)
			}
		} else {
			cancel()
			logrus.Fatalln(err)
		}
	},
}

func init() {
	rootCmd.AddCommand(watchCmd)

	// Here you will define your flags and configuration settings.
	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// watchCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	watchCmd.Flags().IntVar(&notifyConfig.MinLevel, "level", int(etype.Illegal_UnknownUrl), "最低的错误级别")
	watchCmd.Flags().IntVar(&notifyConfig.MinCount, "count", 2, "最低的错误次数")
	watchCmd.Flags().String("dest", "nginx", "输出模式，nginx:输出为nginx配置,aliyun:输出为aliyun配置模式，echo:屏幕打印模式")

	platform.AddFlags(watchCmd.PersistentFlags())
}
